<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <div id="mountNode"></div>
    <script src="../build/g6.js"></script>
    <script>
      /**
       * 该案例演示如何交互复杂的列表组件
       * 内网可以参考：https://riddle.alibaba-inc.com/riddles/3acae792
       *
       */
      const COLLAPSE_ICON = (x, y, r) => {
        return [
          ['M', x, y],
          ['a', r, r, 0, 1, 0, r * 2, 0],
          ['a', r, r, 0, 1, 0, -r * 2, 0],
          ['M', x + 2, y],
          ['L', x + 2 * r - 2, y],
        ];
      };

      const EXPAND_ICON = (x, y, r) => {
        return [
          ['M', x, y],
          ['a', r, r, 0, 1, 0, r * 2, 0],
          ['a', r, r, 0, 1, 0, -r * 2, 0],
          ['M', x + 2, y],
          ['L', x + 2 * r - 2, y],
          ['M', x + r, y - r + 2],
          ['L', x + r, y + r - 2],
        ];
      };

      //注册边
      G6.registerEdge('hvh', {
        draw(cfg, group) {
          const startPoint = cfg.startPoint;
          const endPoint = cfg.endPoint;
          const shape = group.addShape('path', {
            attrs: {
              endArrow: true,
              endArrow: {
                path: 'M 10,0 L -10,-10 L -10,10 Z',
                d: 10,
              },
              stroke: '#A3B1BF',
              path: [
                ['M', startPoint.x, startPoint.y],
                ['L', endPoint.x / 3 + (2 / 3) * startPoint.x, startPoint.y],
                ['L', endPoint.x / 3 + (2 / 3) * startPoint.x, endPoint.y],
                ['L', endPoint.x, endPoint.y],
              ],
            },
          });
          return shape;
        },
      });

      //root节点
      G6.registerNode(
        'tree-node',
        {
          drawShape: (cfg, group) => {
            const rect = group.addShape('rect', {
              attrs: {
                fill: '#0096e0',
              },
            });
            const content = cfg.name;
            const text = group.addShape('text', {
              attrs: {
                text: content,
                x: 0,
                y: 0,
                textAlign: 'left',
                textBaseline: 'middle',
                fill: '#fff',
              },
            });
            const bbox = text.getBBox();
            const hasChildren = cfg.children && cfg.children.length > 0;
            if (hasChildren) {
              group.addShape('marker', {
                attrs: {
                  x: bbox.maxX + 6,
                  y: bbox.minX + bbox.height / 2 - 6,
                  r: 6,
                  symbol: COLLAPSE_ICON,
                  stroke: '#fff',
                  lineWidth: 2,
                },
                className: 'collapse-icon',
              });
            }

            //节点高度(getVGap值保持一致)
            let height = 50;
            //根节点高度：子节点高度+节点间距
            let rootHeight = height * count + height * (count - 1);
            //节点Y坐标
            let nodeY = bbox.minY - 6;
            //根节点Y坐标：节点Y坐标上移节点高度*count
            let rootY = nodeY - height * (count - 1) + 12.5;

            //console.log('rootHeight');
            //console.log(rootHeight);
            //console.log('rootY');
            //console.log(rootY);

            rect.attr({
              x: bbox.minX - 4,
              y: hasChildren ? rootY : nodeY,
              width: bbox.width + (hasChildren ? 26 : 8),
              height: hasChildren ? rootHeight : height,
            });
            return rect;
          },
        },
        'single-shape',
      );

      //子节点
      G6.registerNode('expandNode', {
        draw: function draw(cfg, group) {
          var mainGroup = group.addGroup({
            id: 'main-group',
          });
          var keyShape = mainGroup.addShape('rect', {
            attrs: {
              x: 0,
              y: 0,
              width: 100 + 60 * cfg.values.length,
              height: 50,
              fill: '#f5f5f5',
            },
          });

          // name text
          mainGroup.addShape('text', {
            attrs: {
              text: cfg.name,
              fill: '#000',
              width: 130,
              x: 10,
              y: 32,
            },
          });

          var subGroup = group.addGroup({
            id: 'sub-group',
          });
          cfg.values.forEach(function(data, index) {
            subGroup.addShape('rect', {
              attrs: {
                x: 110 + index * 60,
                y: 0,
                width: 50,
                height: 50,
              },
            });

            subGroup.addShape('text', {
              attrs: {
                text: data.key,
                fill: '#000',
                x: 130 + index * 60,
                y: 20,
                fontSize: 10,
                textBaseline: 'middle',
                className: 'sub-group-text',
              },
            });

            subGroup.addShape('text', {
              attrs: {
                text: data.value,
                fill: '#000',
                x: 130 + index * 60,
                y: 30,
                fontSize: 10,
                textBaseline: 'middle',
                textAlign: 'left',
                className: 'sub-group-text',
              },
            });
          });

          var listGroup = group.addGroup({
            id: 'detail-list-group',
          });

          listGroup.addShape('rect', {
            attrs: {
              width: 100 + 60 * cfg.values.length - 70,
              height: 30 * cfg.properties.length + 20,
              fill: '#fff',
              x: 70,
              y: 30,
            },
          });

          var rectWidth = 100 + 60 * cfg.values.length - 80;
          cfg.properties.forEach(function(property, index) {
            listGroup.addShape('rect', {
              attrs: {
                width: rectWidth,
                height: 30,
                fill: '#e8e8e8',
                x: 80,
                y: 40 * index + 40,
              },
            });
            var count = 0;
            for (var p in property) {
              // 每个rect中添加5个文本
              listGroup.addShape('text', {
                attrs: {
                  text: property[p],
                  fill: '#000',
                  x: 85 + count * (rectWidth / cfg.values.length) - count * 10,
                  y: 40 * index + 40 + 15,
                  fontSize: 10,
                  textBaseline: 'middle',
                  textAlign: 'left',
                },
              });
              count++;
            }
          });
          listGroup.hide();
          return keyShape;
        },
      });

      //graph
      const graph = new G6.TreeGraph({
        container: 'mountNode',
        width: window.innerWidth - 100,
        height: window.innerHeight - 100,
        modes: {
          default: [
            {
              type: 'collapse-expand',
              onChange: (item, collapsed) => {
                const data = item.get('model').data;
                const icon = item.get('group').findByClassName('collapse-icon');
                if (collapsed) {
                  icon.attr('symbol', EXPAND_ICON);
                } else {
                  icon.attr('symbol', COLLAPSE_ICON);
                }
                data.collapsed = collapsed;
                return true;
              },
            },
            'drag-canvas',
            'zoom-canvas',
          ],
        },
        defaultNode: {
          shape: 'tree-node',
          anchorPoints: [
            [0, 0.5],
            [1, 0.5],
          ],
        },
        defaultEdge: {
          shape: 'hvh',
          style: {
            stroke: '#A3B1BF',
          },
        },
        layout: {
          type: 'compactBox',
          direction: 'LR',
          getId: d => {
            return d.id;
          },
          getHeight: () => {
            return 0;
          },
          getWidth: () => {
            return 16;
          },
          getVGap: d => {
            return 50;
          },
          getHGap: () => {
            return 80;
          },
        },
      });

      const data = {
        id: 'root',
        name: 'root',
        children: [
          {
            id: 'shape2',
            //x: 0,
            //y: 50,
            shape: 'expandNode',
            name: '网站引流1',
            values: [
              {
                key: '曝光率',
                value: '1938.33w',
              },
              {
                key: '流入UV',
                value: '1938.33w',
              },
              {
                key: '点击率',
                value: '99.9%',
              },
              {
                key: '占比',
                value: '99.9%',
              },
            ],
            properties: [
              {
                name: '宫格',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '更多应用',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '搜索',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '扫一扫',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '我的Tab',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
            ],
          },

          {
            id: 'shape30',
            //x: 0,
            //y: 50,
            shape: 'expandNode',
            name: '网站引流',
            values: [
              {
                key: '曝光率',
                value: '19.09',
              },
              {
                key: '流入UV',
                value: '910',
              },
              {
                key: '点击率',
                value: '90',
              },
              {
                key: '占比',
                value: '90',
              },
            ],
            properties: [
              {
                name: '宫格',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '更多应用',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '搜索',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '扫一扫',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '我的Tab',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
            ],
          },

          {
            id: 'shape3',
            //x: 0,
            //y: 50,
            shape: 'expandNode',
            name: '网站引流',
            values: [
              {
                key: '曝光率',
                value: '19.09',
              },
              {
                key: '流入UV',
                value: '910',
              },
              {
                key: '点击率',
                value: '90',
              },
              {
                key: '占比',
                value: '90',
              },
            ],
            properties: [
              {
                name: '宫格',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '更多应用',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '搜索',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '扫一扫',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
              {
                name: '我的Tab',
                value1: '1938.33w',
                value2: '1938.33w',
                value3: '99.9%',
                value4: '99.9%',
              },
            ],
          },
        ],
      };

      //统计子节点个数
      let count = -1;

      G6.Util.traverseTree(data, e => {
        count++;
      });

      graph.data(data);
      graph.render();
      graph.fitView();

      // 点击node，展开详情
      graph.on('node:click', function(evt) {
        console.log(graph);

        var target = evt.target;
        var parentGroup = target.get('parent').get('parent');
        var detailGroup = parentGroup.findById('detail-list-group');
        // 将sub-group中的内容网上移动一段距离
        var subGroup = parentGroup.findById('sub-group');
        var keyTexts = subGroup.findAll(function(item) {
          return item.attr('className') === 'sub-group-text';
        });
        var isVisible = detailGroup.get('visible');
        if (isVisible) {
          detailGroup.hide();
          keyTexts.forEach(function(text) {
            var top = text.attr('y');
            text.attr('y', top + 10);
          });

          const layout = {
            type: 'compactBox',
            direction: 'LR',
            getId: d => {
              return d.id;
            },
            getHeight: () => {
              return 0;
            },
            getWidth: () => {
              return 16;
            },
            getVGap: d => {
              return 50;
            },
            getHGap: () => {
              return 80;
            },
          };

          graph.changeLayout(layout);
        } else {
          keyTexts.forEach(function(text) {
            var top = text.attr('y');
            text.attr('y', top - 10);
          });

          detailGroup.show();

          const layout = {
            type: 'compactBox',
            direction: 'LR',
            getId: d => {
              return d.id;
            },
            getHeight: () => {
              return 0;
            },
            getWidth: () => {
              return 16;
            },
            getVGap: d => {
              console.log('ok', d, evt);
              const id = evt.item.get('id');
              if (d.id === id) {
                return 120;
              } else {
                return 50;
              }
            },
            getHGap: () => {
              return 80;
            },
          };

          graph.changeLayout(layout);
        }
        //graph.paint();
      });
    </script>
  </body>
</html>
